package cd.network;

import android.annotation.SuppressLint;
import android.content.Context;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.text.TextUtils;

import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import static android.content.Context.WIFI_SERVICE;

/**
 * 作者：chenda
 * 时间：2019/5/27:11:00
 * 邮箱：
 * 说明：
 */
public class WifiUtils {

    /**
     * 判断wifi是否打开
     * <p>需添加权限 {@code <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>}</p>
     *
     * @return {@code true}: 是<br>{@code false}: 否
     */
    public static boolean getWifiEnabled(Context context) {
        @SuppressLint("WifiManagerLeak")
        WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        return wifiManager.isWifiEnabled();
    }

    /**
     * 打开或关闭wifi
     * <p>需添加权限 {@code <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>}</p>
     *
     * @param enabled {@code true}: 打开<br>{@code false}: 关闭
     */
    public static void setWifiEnabled(Context context,boolean enabled) {
        @SuppressLint("WifiManagerLeak")
        WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        if (enabled) {
            if (!wifiManager.isWifiEnabled()) {
                wifiManager.setWifiEnabled(true);
            }
        } else {
            if (wifiManager.isWifiEnabled()) {
                wifiManager.setWifiEnabled(false);
            }
        }
    }


    /**
     *
     * 获取WIFI列表
     * <p>需要权限{@code <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>}</p>
     * <p>注意Android6.0上需要主动申请定位权限，并且打开定位开关</p>
     *
     * @param context 上下文
     * @return wifi列表
     */
    public static List<ScanResult> getWifiList(Context context) {
        WifiManager wm = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        List<ScanResult> scanResults = wm.getScanResults();

        Collections.sort(scanResults, new Comparator<ScanResult>() {
            @Override
            public int compare(ScanResult scanResult1, ScanResult scanResult2) {
                return scanResult2.level - scanResult1.level;
            }
        });
        return scanResults;
    }

    /**
     * 获取当前链接的WiFi信息
     *
     * @param context 上下文
     * @return 当前wifi数据
     */
    public static WifiInfo getCurrentWifi (Context context) {
        WifiManager wm = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        return wm.getConnectionInfo();
    }

    //通过反射的方式去判断wifi是否已经连接上，并且可以开始传输数据
    public static boolean checkWiFiConnectSuccess() {
        Class classType = WifiInfo.class;
        try {
            Object invo = classType.newInstance();
            Object result = invo.getClass().getMethod("getMeteredHint").invoke(invo);
            return (boolean) result;
        } catch (InstantiationException e) {
            e.printStackTrace();
            return false;
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            return false;
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
            return false;
        } catch (InvocationTargetException e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 获取当前连接WIFI的SSID
     */
    public static String getCurrSSID(Context context) {
        WifiManager wm = (WifiManager) context.getApplicationContext().getSystemService(WIFI_SERVICE);
        if (wm != null) {
            WifiInfo winfo = wm.getConnectionInfo();
            if (winfo != null) {
                String s = winfo.getSSID();
                if (s.length() > 2 && s.charAt(0) == '"' && s.charAt(s.length() - 1) == '"') {
                    return s.substring(1, s.length() - 1);
                }
            }
        }
        return "";
    }

    public static String getWifiEncryptTypeStr (String capabilitie) {
        if (TextUtils.isEmpty(capabilitie)) return null;

        String encryptType;

        if (capabilitie.contains("WPA") && capabilitie.contains("WPA2")) {
            encryptType = "WPA/WPA2 PSK";
        } else if (capabilitie.contains("WPA2")) {
            encryptType = "WPA2 PSK";
        } else if (capabilitie.contains("WPA")) {
            encryptType = "WPA PSK";
        } else if (capabilitie.contains("WEP")) {
            encryptType = "WEP";
        } else {
            encryptType = "NONE";
        }

        return encryptType;
    }

    /**
     * wifi加密方式有5种
     * 0 - WPA/WPA2 PSK
     * 1 - WPA2 PSK
     * 2 - WPA PSK
     * 3 - WEP
     * 4 - NONE
     * @param capabilitie
     * @return
     */
    public static int getWifiEncryptType (String capabilitie) {
        if (TextUtils.isEmpty(capabilitie)) return -1;

        int encryptType;

        if (capabilitie.contains("WPA") && capabilitie.contains("WPA2")) {
            encryptType = 0;
        } else if (capabilitie.contains("WPA2")) {
            encryptType = 1;
        } else if (capabilitie.contains("WPA")) {
            encryptType = 2;
        } else if (capabilitie.contains("WEP")) {
            encryptType = 3;
        } else {
            encryptType = 4;
        }

        return encryptType;
    }


    /**
     * @des 连接已经保存过配置的wifi
     * @param context
     * @param ssid
     */
    public static void connectWifi (Context context, String ssid) {

        if (!getWifiEnabled(context)) return;

        WifiManager wm = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        WifiConfiguration wc = new WifiConfiguration();

        wc.SSID = "\"" + ssid + "\"";

        WifiConfiguration configuration = getWifiConfig(context, ssid);
        if (configuration != null) {
            wm.enableNetwork(configuration.networkId, true);
        }

    }

    /**
     * @des 连接没有配置过的wifi
     * @param context
     * @param ssid
     * @param password
     * @param encryptType
     */
    public static boolean connectWifi (Context context, String ssid, String password, int encryptType) {

        if (!getWifiEnabled(context)) return false;

        WifiManager wm = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        WifiConfiguration wc = new WifiConfiguration();
        wc.allowedAuthAlgorithms.clear();
        wc.allowedGroupCiphers.clear();
        wc.allowedKeyManagement.clear();
        wc.allowedPairwiseCiphers.clear();
        wc.allowedProtocols.clear();

        wc.SSID = "\"" + ssid + "\"";

        WifiConfiguration configuration = getWifiConfig(context, ssid);
        if (configuration != null) {
            connectWifi (context, ssid);
            return true;
//            wm.removeNetwork(configuration.networkId);
        }

        switch (encryptType) {
            case 4://不加密
                wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
                break;

            case 3://wep加密
                wc.hiddenSSID = true;
                wc.wepKeys[0] = "\"" + password +"\"";
                wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
                wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
                wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
                wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
                wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
                wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);

                break;
            case 0: //wpa/wap2加密
            case 1: //wpa2加密
            case 2: //wpa加密

                wc.preSharedKey = "\"" + password + "\"";
                wc.hiddenSSID = true;
                wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
                wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
                wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
                wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
                wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
                wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
                wc.status = WifiConfiguration.Status.ENABLED;
                break;
        }

        int network = wm.addNetwork(wc);
        return wm.enableNetwork(network, true);
    }

    public static void disConnectWifi (Context context, int networkId) {
        WifiManager wm = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        wm.disableNetwork(networkId);
        wm.disconnect();
    }

    /**
     * @des 清除wifi配置信息
     * @param context
     * @param ssid
     */
    public static void clearWifiInfo(Context context, String ssid) {

        WifiManager wm = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);

        String newSSID = "\"" + ssid + "\"";

        if (!(ssid.startsWith("\"") && ssid.endsWith("\""))) {
            newSSID = "\"" + ssid + "\"";
        } else {
            newSSID = ssid;
        }

        WifiConfiguration configuration = getWifiConfig(context, newSSID);
        configuration.allowedAuthAlgorithms.clear();
        configuration.allowedGroupCiphers.clear();
        configuration.allowedKeyManagement.clear();
        configuration.allowedPairwiseCiphers.clear();
        configuration.allowedProtocols.clear();

        if (configuration != null) {

            wm.removeNetwork(configuration.networkId);
            wm.saveConfiguration();
        }
    }

    public static WifiConfiguration getWifiConfig (Context context, String ssid) {

        if (TextUtils.isEmpty(ssid)) return null;

        String newSSID;

        if (!(ssid.startsWith("\"") && ssid.endsWith("\""))) {
            newSSID = "\"" + ssid + "\"";
        } else {
            newSSID = ssid;
        }

        WifiManager wm = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        List<WifiConfiguration> configuredNetworks = wm.getConfiguredNetworks();
        if(configuredNetworks == null)
            return null;
        for (WifiConfiguration configuration : configuredNetworks) {
            if (newSSID.equalsIgnoreCase(configuration.SSID)) {
                return configuration;
            }
        }

        return null;
    }
}
